package domain.dao.impl;

import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import util.SpringUtils;
import domain.dao.interfaces.IDAOPhoneNumber;
import domain.entities.impl.Contact;
import domain.entities.impl.PhoneNumber;
import domain.entities.interfaces.IContact;
import domain.entities.interfaces.IPhoneNumber;

public class DAOPhoneNumber extends HibernateDaoSupport implements IDAOPhoneNumber {

	private HibernateTemplate hibernateTemplate;



	public void init() {
		setHibernateTemplate(getSessionFactory());
	}
	
	public void setHibernateTemplate(SessionFactory sessionFactory){
		this.hibernateTemplate= new HibernateTemplate(sessionFactory);
	}

	/* (non-Javadoc)
	 * @see domain.dao.impl.IDAOPhoneNumber#addPhoneNumber(org.hibernate.Session, java.lang.String, java.lang.String, int)
	 */
	public int addPhoneNumber(
			final String phoneKind, final String phoneNumber, final int idContacts) 
					throws Exception {

		ApplicationContext context = SpringUtils.getApplicationContext();

		IPhoneNumber phoneNumberObj = (IPhoneNumber) context.getBean("beanPhoneNumber");
		IContact c = (IContact)hibernateTemplate.get(Contact.class, idContacts);


		phoneNumberObj.setPhoneKind(phoneKind);
		phoneNumberObj.setPhoneNumber(phoneNumber);
		phoneNumberObj.setContacts(c);


		hibernateTemplate.save(phoneNumberObj);


		return phoneNumberObj.getId();
	}

	/* (non-Javadoc)
	 * @see domain.dao.impl.IDAOPhoneNumber#deletePhoneNumber(org.hibernate.Session, int)
	 */
	public void deletePhoneNumber(int id) throws Exception {

		IPhoneNumber phoneNumber = (IPhoneNumber) hibernateTemplate.get(
				PhoneNumber.class, id);


		hibernateTemplate.delete(phoneNumber);
	}

	/* (non-Javadoc)
	 * @see domain.dao.impl.IDAOPhoneNumber#updatePhoneNumber(org.hibernate.Session, int, java.lang.String, java.lang.String)
	 */
	public void updatePhoneNumber(
			IPhoneNumber p,
			int id, final String phoneKind,
			final String phoneNumber) throws Exception {

		int oldVersion = p.getVersion();
		int newVersion;

		
		
		p.setPhoneKind(phoneKind);
		p.setPhoneNumber(phoneNumber);

		
		
		//update into db
		hibernateTemplate.merge(p);
		hibernateTemplate.flush();
		
		
		
		newVersion = p.getVersion();
		if(oldVersion != newVersion) {
			
			IContact c = hibernateTemplate.get(
					Contact.class, p.getContacts().getId());
			
			c.setChildsVersion(c.getChildsVersion()+1);
			hibernateTemplate.merge(c);
		}
	}

	/* (non-Javadoc)
	 * @see domain.dao.impl.IDAOPhoneNumber#getByContactId(int)
	 */
	public List<IPhoneNumber> getByContactId(final int contactId) {

		return (List<IPhoneNumber>) hibernateTemplate
				.execute(new HibernateCallback<List<IPhoneNumber>>() {

					public List<IPhoneNumber> doInHibernate(Session session)
							throws HibernateException, SQLException {


						//Business code

						/*
						 *  "contacts" instead of "contact" for phonenumber is due to an error in class diagram,
						 *  there is only one contact
						 */
						Query query = session.createQuery("select p from PhoneNumber p where p.contacts.id = :contactId");
						query.setParameter("contactId", contactId);
						return query.list();
					}
				});
	}
}